import request from '../../vue2-flow/src/utils/request'
import { Groups } from './flow.mock'
import { API } from './BaseApi'

import store from '../../vue2-flow/src/store'
import SourceNodeGroupApi from './SourceNodeGroupApi'
import Utils from '../../vue2-flow/src/utils/Common'
import { useFlowStore } from "@/store/modules/flow/flowStore";
import { FlowApi } from "@/api/FlowApi";
import { NodeApi } from "@/api/NodeApi";

const BaseURL = 'http://localhost:8080/flow'

let FlowStore = null
const GetFlowStore = () => {
  if (Utils.IsEmpty(FlowStore)) {
    FlowStore = useFlowStore()
  }
  return FlowStore;
}
const mapProcessor = (p) => {
  return {
    ...p, port: {
      outputActive: false, inputActive: false
    }
  }
}

export const mapProcessGroup = processGroup => {
  const { id, processors, connections, processGroups } = processGroup || {}
  const ps = processors && processors.map(mapProcessor) || []
  const links = connections || []
  const groups = processGroups && processGroups.map(g => ({
    ...g, count: g.processors && g.processors.length || g.count || 0
  })) || []
  return {
    processors: ps, links, groups, id
  }
}

export const UpdateLocalFlowData = (flowJson) => {
  const updated = mapProcessGroup(JSON.parse(flowJson))
  store.commit('flow/chat/SET_PROCESS_GROUP', updated)
}

/**
 * Groups
 * 设置组件节点
 * @returns {Promise<[{name: string, id: string, title: string, items: [{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean},{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean},{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean}]},{name: string, id: string, title: string, items: [{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean},{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean}]},{name: string, id: string, title: string, items: [{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean},{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean},{iconOnRight: boolean, name: string, icon: string, style: {backgroundColor: string, height: number}, hasOutput: boolean, id: string, hasInput: boolean}]}]>}
 */
export const fetchProcessorTypes = async() => {
  const sssd = await new SourceNodeGroupApi().GetSourceNodeGroup()
  // return Groups
  return sssd.groups
}

export const fetchProcessGroup = async(id = 'root') => {
  const processGroup = await request({
    url: `${BaseURL}/dataflow/process-groups/${id}`, method: 'get'
  })
  return mapProcessGroup(processGroup)
}

/**
 * 添加节点，创建一个新的节点
 * @param typeId
 * @param x
 * @param y
 * @param maxX
 * @param maxY
 * @param groupId
 * @returns {Promise<{groups: (*|*[]), links: (*|*[]), processors: (*|*[]), id: *}>}
 */
export const createProcessor = async(typeId, { x, y, maxX, maxY }, groupId = 'root') => {
  try {
    const CurrentFlow = GetFlowStore().CurrentFlow
    const processGroup = await NodeApi.Save({ FlowId: CurrentFlow.id, NodeHubId: typeId, X: x, Y: y })
    //const processGroup = await API.FlowApi.AddFlowNode(CurrentFlow.id, typeId, x, y, maxX, maxY, groupId)
    // const _new = processGroup.Data
    const ssss = Utils.GetParents(JSON.parse(processGroup.Data))
    return mapProcessGroup(ssss)
  } catch (e) {
    alert("createProcessor error:" + e)
  }
  let item = null
  Groups.forEach((d, index) => {
    d.items.forEach((v, vi) => {
      if (v.id === typeId) {
        item = Object.assign({}, v)
      }
    })
  })
  item.style.color = item.style.backgroundColor
  item.id = new Date().getTime()
  const ps = item
  ps.rect = {
    x: x, y: y, w: 111, h: 33
  }
  ps.label = item.name
  let cu = localStorage.getItem('processGroup')
  if (cu != null) {
    cu = JSON.parse(cu)
    cu.processors.push(ps)
  } else {
    cu = {
      id: null, processors: [ps]
    }
  }
  const _newGroup = Object.assign({}, cu, item)
  _newGroup.id = new Date().getTime()
  localStorage.setItem('processGroup', JSON.stringify(_newGroup))
  return mapProcessGroup(_newGroup)
}

/**
 * 移动节点
 * @param node
 * @param groups
 * @param groupId
 * @returns {Promise<{groups: (*|*[]), links: (*|*[]), processors: (*|*[]), id: *}>}
 * @constructor
 */
export const UpdateSnippet = async(node, groups, groupId = 'root') => {
  const CurrentFlow = GetFlowStore().CurrentFlow
  for (const nodeElement of node) {
    nodeElement.Parents = []
    nodeElement.Children = []
  }
  const processGroup = await FlowApi.UpdateFlowNode(CurrentFlow.id, JSON.stringify(node))
  const ssss = Utils.GetParents(processGroup)
  return mapProcessGroup(ssss)
}

/**
 * 创建新连接
 * @param source
 * @param sourcePort
 * @param target
 * @param groupId
 * @returns {Promise<{groups: (*|*[]), links: (*|*[]), processors: (*|*[]), id: *}>}
 */
export const createConnection = async({ source, sourcePort, target }, groupId = 'root') => {
  const CurrentFlow = GetFlowStore().CurrentFlow
  const Conn = {
    FlowId: CurrentFlow.id,
    SourceNodeId: source.id,
    TargetNodeId: target.id,
    SourcePort: sourcePort,
  }
  const processGroup = await NodeApi.Connection(Conn)
  const _new = JSON.parse(processGroup.Data)
  const ssss = Utils.GetParents(_new)
  return mapProcessGroup(ssss)
}

/**
 * 克隆节点
 * @param SourceFlowId
 * @param processors
 * @param links
 * @param groupId
 * @returns {Promise<{groups: (*|*[]), links: (*|*[]), processors: (*|*[]), id: *}>}
 */
export const cloneSnippet = async({ SourceFlowId, processors, links }, groupId = 'root') => {
  // const NodeIds = processors.map((n) => n.id)
  const NodeIds = processors
  const CurrentFlow = GetFlowStore().CurrentFlow
  const processGroup = await API.FlowApi.CloneNode(SourceFlowId, CurrentFlow.id, JSON.stringify(NodeIds), JSON.stringify(links))
  const _new = JSON.parse(processGroup)
  const ssss = Utils.GetParents(_new)
  return mapProcessGroup(ssss)
}

export const addGroup = async({ processors, links }, groupId = 'root') => {
  const processGroup = await request({
    url: `${BaseURL}/process-groups/${groupId}/process-groups`, method: 'post', data: {
      processors, connections: links
    }
  })
  return mapProcessGroup(processGroup)
}

/**
 * 删除节点
 * @param processors
 * @param links
 * @param groups
 * @param groupId
 * @returns {Promise<{groups: (*|*[]), links: (*|*[]), processors: (*|*[]), id: *}>}
 */
export const deleteSnippet = async({ processors, links, groups }, groupId = 'root') => {
  const CurrentFlow = GetFlowStore().CurrentFlow
  const processGroup = await NodeApi.DeleteNode(CurrentFlow.id, JSON.stringify(processors), JSON.stringify(links))
  const ssss = Utils.GetParents(JSON.parse(processGroup.Data))
  return mapProcessGroup(ssss)
}

export async function ungroup (groupId, parentID = 'root') {
  const processGroup = await request({
    url: `${BaseURL}/process-groups/${groupId}/ungroup`, method: 'put', params: {
      parentID
    }
  })
  return mapProcessGroup(processGroup)
}

/**
 * 更新mes的请求参数
 * @param ApiName
 * @param Request
 * @constructor
 */
export const SaveMesRequestParams = (ApiName, Request, callback) => {
  NodeApi.SaveMesNodeRequestParams({ ApiName: ApiName, RequestJson: JSON.stringify(Request) }).then((res) => {
    callback(res)
  })
}

/**
 * 获取mes的请求参数
 * @param ApiName
 * @param callback
 * @constructor
 */
export const GetMesNodeRequestParams = (ApiName, callback) => {
  API.FlowApi.GetMesNodeRequestParams(ApiName).then((res) => {
    callback(JSON.parse(res))
  })
}

/**
 * 获取所有节点的详细信息
 * @param callback
 * @constructor
 */
const GetAllFlowNodeDetailInfo = async(callback) => {
  const Res = await FlowApi.GetAllFlowNodeDetail()
  callback(JSON.parse(Res.Data))
}
// 1.2 创建防抖函数（缓存为模块变量，确保防抖状态唯一）
// const debouncedGetAllFlowNodeDetail = Utils.debounce(
//   fetchAllFlowNodeDetailCore, // 核心逻辑（防抖的目标函数）
//   DEBOUNCE_DELAY // 防抖延迟时间（例如 500ms）
// );

export const GetAllFlowNodeDetailInfoDebounce = (callback) => {
  const DebounceFun = Utils.debounce(GetAllFlowNodeDetailInfo, 500)
  DebounceFun(callback);
}

/**
 * 修改节点的参数值
 * @param NodeId
 * @param Param
 * @param Value
 * @param Callback
 * @constructor
 */
export const UpdateFlowNodeParam = (NodeId, Param, Value, Callback) => {
  const CurrentFlow = GetFlowStore().CurrentFlow
  API.FlowApi.UpdateFlowNodeParam(CurrentFlow.id, NodeId, Param, Value).then((res) => {
    Callback(res)
  })
}
